using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace cs2335.lab5
{
    public class CCTForm : Form, ICCTForm
    {
        private List<IComponent> components;
        private IComponent focusHolder;
        private IComponent prevFocusHolder;
        private bool focusHeld;

        public IComponent FocusHolder
        {
            get { return focusHolder; }
            set {
                if (focusHolder != null)
                    focusHolder.OnLostFocus(null);
                focusHolder = value;
                value.OnGotFocus(null);
            }
        }

        public IComponent PrevFocusHolder
        {
            get { return prevFocusHolder; }
            set { prevFocusHolder = value; }
        }

        public CCTForm()
        {
            components = new List<IComponent>();
            this.GotFocus += new EventHandler(OnGotFocus);
            this.LostFocus += new EventHandler(OnLostFocus);
            this.KeyPress += new KeyPressEventHandler(OnKeyPress);
            this.MouseClick += new MouseEventHandler(OnMouseClick);
            this.MouseDown += new MouseEventHandler(OnMouseDown);
            this.MouseUp += new MouseEventHandler(OnMouseUp);
            this.MouseMove += new MouseEventHandler(OnMouseMove);
            this.KeyDown += new KeyEventHandler(OnKeyDown);
            focusHolder = null;
            prevFocusHolder = null;
            focusHeld = true;
        }

        void OnMouseDown(object sender, MouseEventArgs e)
        {
            /// dprather
            /// if we're using the menu, make sure the menu gets the action
            /// and not another component underneath the menu
            if (focusHolder != null && focusHolder.Name == "Menu" && focusHolder.Bounds.Contains(e.Location))
            {
                return;
            }

            foreach (IComponent c in components)
            {
                if (!c.Hidden && c.Bounds.Contains(e.Location))
                {
                    c.OnMouseDown(e);
                    if (focusHolder != c)
                    {
                        if (focusHolder != null)
                            focusHolder.OnLostFocus(null);
                        prevFocusHolder = focusHolder;
                        focusHolder = c;
                        c.OnGotFocus(null);
                    }
                    break;
                }
            }
        }

        void OnMouseUp(object sender, MouseEventArgs e)
        {
            if (focusHolder != null)
                focusHolder.OnMouseUp(e);
        }

        void OnMouseMove(object sender, MouseEventArgs e)
        {
            if (focusHolder != null)
                focusHolder.OnMouseMove(e);
        }

        public void Add(IComponent comp)
        {
            comp.Owner = this;
            components.Add(comp);
            Invalidate();
        }

        void OnMouseClick(object sender, MouseEventArgs e)
        {
            /// dprather
            /// if we're using the menu, make sure the menu gets the action
            /// and not another component underneath the menu
            if (focusHolder != null && focusHolder.Name == "Menu" && focusHolder.Bounds.Contains(e.Location))
            {
                focusHolder.OnMouseClick(e);
                return;
            }

            foreach (IComponent c in components)
            {
                if (!c.Hidden && c.Bounds.Contains(e.Location))
                {
                    //MessageBox.Show("gave mouse click to: " + c.Text);
                    c.OnMouseClick(e);
                    if (focusHolder != c)
                    {
                        if (focusHolder != null)
                            focusHolder.OnLostFocus(null);
                        prevFocusHolder = focusHolder;
                        focusHolder = c;
                        c.OnGotFocus(null);
                    }
                    break;
                }
            }
        }

        public void OnGotFocus(object sender, EventArgs e)
        {
            focusHeld = true;
            if (focusHolder != null)
                focusHolder.OnGotFocus(e);
        }

        public void OnLostFocus(object sender, EventArgs e)
        {
            focusHeld = false;
            if (focusHolder != null)
                focusHolder.OnLostFocus(e);
        }

        public void OnKeyPress(object sender, KeyPressEventArgs e)
        {
            if (focusHeld && focusHolder != null)
                focusHolder.OnKeyPress(e);
        }

        public void OnKeyDown(object sender, KeyEventArgs e)
        {
            if (focusHeld && focusHolder != null)
                focusHolder.OnKeyDown(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            foreach (IComponent c in components) {
                c.OnPaint(e);
            }
        }
    }
}
